C/C++ Basic API
按照VoIP & IM Mobile SDK API的封装原则,C/C++ Basic API接口可划分为:基本功能接口、通话功能接口和对讲功能接口等三个功能模块。
下面分别说明各接口功能模块的具体使用方法。
基本功能接口
基本功能接口的函数原型参见“freepp_sdk.h”文件,主要提供应用管理、即时消息和群组管理功能。
应用/账号管理
初始化SDK库
| 函数原型 | Bool Initialize(char* appKey, void* sdkDelegate); |
|---|---|
| 参数 | appKey:字符串,用于标识第三方APP的授权码。 sdkDelegate:任意指针类型,APP代理者对象的指针。(APP代理者对象主要负责实现SDK的回调函数,对象原型参见FreePPSDKDelegate) |
| 返回值 | 布尔型,客户端初始化结果。成功返回true,失败返回false。 |
| 说明 | 初始化和启动SDK客户端模块。 注:APP授权码和云端服务入口地址需预先申请,初始化SDK前需预先通过SetParameter接口设置用户数据库路径和云端服务入口地址。 |
| 示例 |
char dbPath[1024] = “数据库文件的存放路径”;// 设置SDK数据库路径
|
绑定APP用户账号
| 函数原型 | int BindAppAccount(char*appUserAccount,bool mustAuth,char *outFreePPID); |
|---|---|
| 参数 | appUserAccount:字符串,App帐号(长度不超过40字节)。 mustAuth:布尔值,此参数为true时,SDK强制到服务器进行远程身份验证,否则SDK将自动判断是否需要到服务器上进行认证,或者在本地数据库中完成认证。这样,APP可以自己决定是否要互踢或者快速登录。 outFreePPID:输出参数,字符串,用于接收与此账号绑定的freepp号码。如果绑定成功,该参数则赋值为该freepp号码。 |
| 返回值 | 整型,0=绑定APP账号和通信号码成功,其它值=错误代码 |
| 说明 | 首先验证App的合法性,然后分配和绑定通信号码,最后登录即时通信系统的云平台。 注:当第一次bind时,需要访问服务器,APP要确保网络是连接的。APP除必须采用强制认证方式(例如:强制到服务器验证身份)的情况之外,在其它情况下推荐使用自动验证方式(mustAuth=FALSE),以提高登录的速度。 |
| 示例 |
char freeppID[256] = { 0 };
char account[256] = “APP账号”;
if (strlen(account) > 40)
{
AfxMessageBox(_T("用户名超过40字节,请重新输入!"));
return -1;
}
if( FreePPSDK::BindAppAccount(account, false, freeppID)!= 0)
{
AfxMessageBox(_T("appKey验证失败或者绑定失败!"));
return -1;
}
|
登出当前绑定的APP账号
| 函数原型 | int LogoutAppAccount() |
|---|---|
| 参数 | 无 |
| 返回值 | 整型,0=成功,其它=错误代码。 -15: SDK未初始化或没有绑定成功。 |
| 说明 | 重置当前帐号,清除本地的账号记录和缓存的消息。 |
| 示例 |
int res = FreePPSDK::LogoutAppAccount();
if (res != 0)
{
AfxMessageBox(_T("Logout失败,res = %d!",res));
return;
}
|
查询通信号码
| 函数原型 | intQueryFreePPIDByAppAccount(const char* jsonAccountArray, char*outJsonAccountFreePPID); |
|---|---|
| 参数 | jsonAccountArray:JSON字符串,指定查询目标的APP账号。例如: ["abner1","abner2","abner3","abner4"]。 outJsonAccountFreePPID:输出参数,JSON字符串,用于接收SDK返回的通信号码信息。例如: {"abner1":"30905341","abner2":"30905127","abner3":"30905543","abner4":"30904794"}。 有关JSON字符串的解析可参考示例程序 |
| 返回值 | 整型,0=查询通信号码成功,其它值=错误代码; |
| 说明 | 根据APP账号查询通信号码。 |
| 示例 |
vector
|
查询APP账号
| 函数原型 | intQueryAppAccountByFreePPID(const char* jsonFreePPIDArray, char* outJsonFreePPIDAccount); |
|---|---|
| 参数 | jsonFreePPIDArray:JSON字符串,指定查询目标的APP账号,例如: ["30905341","30905127","30905543","30904794"]。 outJsonFreePPIDAccount:输出参数,JSON字符串,用于接收SDK返回的APP账号信息,例如:{"30905341":"abner1","30905127":"abner2","30905543":"abner3","30904794":"abner4"}。 |
| 返回值 | 整型,0=查询APP账号成功,其它值=错误代码; |
| 说明 | 根据通信号码(FreePPID)查询APP账号。 |
| 示例 |
vector
|
修改SDK参数配置
| 函数原型 | intSetParameter(char *name, char *value); |
|---|---|
| 参数 | name:字符串,参数名称。 value:字符串,参数值。 |
| 返回值 | 整型,0-设置成功,错误码参考错误码表。 |
| 说明 | 设置SDK内部的配置参数。 注:目前支持的配置参数参见附录1。 |
| 示例 |
参见Initialize代码。
|
读取SDK参数配置
| 函数原型 | voidGetParameter(char *name, char *outValue); |
|---|---|
| 参数 | name:输入参数,字符串,参数名称。 outValue:输出参数,字符串,用于接收返回的参数值。 |
| 返回值 | 无 |
| 说明 | 读取SDK内部的参数值。 |
| 示例 |
参见Initialize示例代码。
|
追踪错误代码
| 函数原型 | int GetLastErrorCode(); |
|---|---|
| 参数 | 无 |
| 返回值 | 整型,错误代码。如果没有错误,则返回0. |
| 说明 | 读取最后一次接口调用失败的错误码。 注:此接口为线程安全的,即保证不同线程最后一次错误是独立保存的,如果调用此接口后,SDK即会清除当前线程的错误码。 |
| 示例 |
int lastErrorCode = GetLastErrorCode();
switch (lastErrorCode)
{
caseSUCCESS_CODE:
{
AfxMessageBox(_T("无错误!"));
}
break;
caseERROR_NETWORK_NO_CONNECTION:
{
AfxMessageBox(_T("没有网络链接!"));
}
break;
caseERROR_FREEPP_API_TIMEOUT:
{
AfxMessageBox(_T("API请求超时或出错!"));
}
break;
caseERROR_ROOTCS_INVALID:
{
AfxMessageBox(_T("rootcs没有设置!"));
}
break;
caseERROR_PARAMETER:
{
AfxMessageBox(_T("参数不合法!"));
}
break;
caseERROR_FREEPP_SDK_UNINITIALIZED:
{
AfxMessageBox(_T("FreePP SDK未初始化或绑定成功!"));
}
break;
default:
break;
}
|
响应系统消息
| 函数原型 | CALLBACK virtual voidonSystemEvent(int eventType, void* dataOjbect) = 0; |
|---|---|
| 参数 | eventType:输入参数,整型,事件类型,包含:1=当前用户被踢出;对应的 data 为 NULL。 dataOjbect:输入参数,根据事件类型对应不同的数据对象,也可以为 NULL。 |
| 返回值 | 无 |
| 说明 | 向APP推送与当前用户帐号有关的系统事件。 |
| 示例 |
voidFreePPSDKDelegate::onSystemEvent(inteventType, void* dataOjbect)
{
char log[256];
switch (eventType) {
caseEVENT_TYPE_KICKOUT: // 1=当前用户被踢出
sprintf(log,"EVENT_TYPE_KICKOUT = 1");
//异步执行登出当前绑定的APP账号
FreePPSDK::LogoutAppAccount();
break;
default:
break;
}
}
|
即时消息
发送一对一消息
| 函数原型 | int SendMessage (char* dstFreePPID, char* mimeType, char* textContent, char* filePath, char* messageID, char* outMessageID); |
|---|---|
| 参数 | dstFreePPID:字符串,目标用户的通信号码。 mimeType:字符串,多媒体消息的类型,例如:”text/plain” textContent:字符串,文本消息的内容,其格式根mimeType来区分。如果为text/plain则为纯文本字符串。 filePath:字符串,消息文件的本地文件路径。 messageID:字符串,如果是重试发送消息的消息ID。 outMessageID:输出参数,字符串,用于接收消息ID的字符串缓冲区。消息ID格式为“本地通信号码-Unix时间戳(秒)-两位序号”。如果发送消息失败,则此字符串为空。 |
| 返回值 | 整型,消息处理结果。0=消息已被排入发送队列,等待发送;其它值=错误代码。 |
| 说明 | 向指定的用户异步地发送一对一的多媒体消息。 注:此接口为异步接口,可触发回调函数包括onSendMessageEvent和onUploadAttacthmentProgressEvent。 如果messageID参数有值,则SDK会判断此消息ID是否有效。对于有效的消息,SDK将重新发送此消息ID对应的消息内容;对于无效的消息,SDK则直接返回错误代码。 |
| 示例 |
// m_textContent需发送的文本,文本长度不大于1024字节
if (m_textContent.GetLength() >1024)
{
AfxMessageBox(_T("文本内容太长,请分条发送!"));
return;
}
char dstFreePP[256] = { 0 };
char mimeType[32] = { 0 };
char textContent[FREEPP_MMS_TEXT_MAX_LENGTH] = { 0 };
char retryMsgId[256] = { 0 };
char filePath[512] = { 0 };
CopyString(m_dstFreePPUser, dstFreePP, 256);
vector
|
发送群组消息
| 函数原型 | int SendGroupMessage (char *dstGroupID, char *mimeType, char *textContent, char *filePath, char *messageID, char *outGroupMesaageID); |
|---|---|
| 参数 | dstGroupID:字符串,目标群组的唯一标识符。 mimeType:字符串,多媒体消息的类型。 textContent:字符串,文本消息的内容,其格式根据mimeType来区分。 filePath:字符串,消息文件的本地文件路径。 messageID:字符串,如果是重试发送消息的消息ID。 outMessageID:输出参数,字符串,用于接收消息ID的缓冲区。消息ID格式为:“通信号码-Unix时间戳(秒)-两位序号”。如果发送失败,则返回NULL。 |
| 返回值 | 整型,消息处理结果。0=消息已被排入发送队列,等待发送;其它值=错误代码。 |
| 说明 | 向指定的群组异步地发送一对多的多媒体消息。 注:此接口为异步接口,可触发回调函数OnSendMessageEvent和onUploadAttacthmentProgressEvent。 如果messageID参数有值,则SDK会判断此消息ID是否有效。对于有效的消息,SDK将重新发送此消息ID对应的消息内容;对于无效的消息,SDK则直接返回错误代码。 注:群组的标识符ID可通过调用CreateGroupChat接口,或者接收到群组消息时从通知中获得。 |
| 示例 |
if (m_dstGroupID.GetLength() == 0)
{
AfxMessageBox(_T("目标群ID为空!"));
return;
}
// Unicode to Multibyte coding
char mimeType[32] = { 0 };
CopyString(m_msgType, mimeType, sizeof(mimeType));
char retryMsgId[256] = { 0 };
char filePath[256] = { 0 };
CopyString(m_filePath, filePath, sizeof(filePath));
char groupMsgID[256] = { 0 };
char groupID[64] = { 0 };
CopyString(m_dstGroupID, groupID, 64);
char groupMsgData[FREEPP_MMS_TEXT_MAX_LENGTH] = { 0 };
if (m_textContent.GetLength() |
清除缓存的消息
| 函数原型 | void ClearMessage(char* messageIDArray); |
|---|---|
| 参数 | messageIDArray:JSON字符串,被释放的消息的标识符列表。例如:[”call-id1”,”call-id2”]。 |
| 返回值 | 无 |
| 说明 | 清除SDK内部存储的消息记录。 注:APP在接收或发送消息成功后,可调用此函数以清除SDK中的缓存记录。 |
| 示例 |
vector
|
检查新消息
| 函数原型 | void CheckNewMessage(); |
|---|---|
| 参数 | 无 |
| 返回值 | 无 |
| 说明 | 客户端主动到服务器上检查和下载新消息。 注:此接口为异步接口,可触发回调函数onReceiveMessageEvent。 |
| 示例 |
FreePPSDK::CheckNewMessage( );
|
响应消息发送结果
| 函数原型 | virtual void onSendMessageEvent(char* messageID, int sendResult) = 0; |
|---|---|
| 参数 | messageID:字符串,发送消息的唯一标识ID。 sendResult:整型,发送消息的结果。0=成功,发送失败参照错误码表。 |
| 返回值 | 无 |
| 说明 | APP通过此接口获得一对一或群聊消息消息的发送状态。 注:对于发送文本消息和文件消息,均使用此回调函数来获得消息发送结果;对于文件型消息,还可以通过onUploadMessageAttachmentProgressEvent回调函数获取文件传输的进度。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此回调函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
voidFreePPSDKDelegate::onSendMessageEvent(char* messageID, intsendResult)
{
CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
char msgID[256] = { 0 };
char groupMsgID[256];
CopyString(dlg->mmsTestDlg->m_sendMsgID, msgID, 256);
CopyString(dlg->mmsTestDlg->m_sendGroupMsgID, groupMsgID, 256);
if (strcmp(msgID, messageID) == 0)
{
//异步处理一对一消息结果
}
elseif (strcmp(groupMsgID,messageID) == 0)
{
//异步处理群组消息结果
}
}
|
获取到新消息
| 函数原型 | virtual voidonReceiveMessageEvent(int msgType, void *msgObject) = 0; |
|---|---|
| 参数 | msgType:整型,消息类型,取值为 0 = 一对一消息/群组消息类型; 1 = 加入群组通知类型; 2 = 离开群组类型; 3 = 消息接收状态通知类型 msgObject:消息对象,每种消息类型分别对应不同的对象,具体定义参考附录3“消息对象对照表” |
| 返回值 | 无 |
| 说明 | App通过此回调函数接收一对一或群组消息。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此回调函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
voidFreePPSDKDelegate::onReceiveMessageEvent(intmsgType, void * msgObject)
{
...
switch (msgType)
{
CaseMESSAGE_BOJECT_TYPE_MMS: // 一对一消息/群组消息
{
Message * messageOjbect = (Message *)msgObject;
// 异步处理接收的消息
…
// 如果是单聊则报告消息的状态
if (messageOjbect->sessionType == SESSION_SINGLE_CHAT)
{
// 向发送端报告:已送达
FreePPSDK::ReportMessageStatus(messageOjbect->srcFreePPID,messageOjbect->messageID,MESSAGE_STATUS_RECEIVED);
//向发送端报告:已读
FreePPSDK::ReportMessageStatus
(messageOjbect->srcFreePPID, messageOjbect->messageID,MESSAGE_STATUS_READED);
}
}
break;
caseMESSAGE_BOJECT_TYPE_JOIN: // 加入群组通知
{
JoinGroupMessage * joinGroupMessage = (JoinGroupMessage *)msgObject;
// 异步处理接收的消息
// ......
}
break;
caseMESSAGE_BOJECT_TYPE_LEAVE: // 离开群组
{
LeaveGroupMessage * leaveGroupMessage = (LeaveGroupMessage *)msgObject;
// 异步处理接收的消息
// ......
}
break;
caseMESSAGE_BOJECT_TYPE_STATUS:// 消息送达状态通知
{
MessageStatus * messageStatus = (MessageStatus *)msgObject;
// 异步处理接收的消息
// ......
}
break;
default:
break;
}
}
|
报告消息接收状态
| 函数原型 | intReportMessageStatus(char *dstFreePPID, char *messageID, int status); |
|---|---|
| 参数 | dstFreePPID:字符串,目标用户的通信号码。 messageID:字符串,消息的唯一标识ID。 status:整型,发送消息接收状态通知的类型,包括:1 = 已送达,2 = 已读。 |
| 返回值 | 整型,报告处理结果。0=已加入发送队列发送,-1无网络无法发送。 |
| 说明 | 向指定用户发送一对一消息接收状态通知,包括消息送达和已读通知。 |
| 示例 |
详见onReceiveMessageEvent示例代码。
|
下载消息附件
| 函数原型 | intDownloadMessageAttachment(char *messageID, int isThumbnail, char *filePath); |
|---|---|
| 参数 | messageID:字符串,要求下载的消息的唯一标识。 isThumbnail:整型,是否要下载缩略图,1-下载缩略图,0-下载原图,非图片类型无效参数。 filePath:字符串,下载到本地的文件路径,包含文件的名称。 |
| 返回值 | 整型,下载附件的处理结果。0=已加入到下载队列中,其他错误码参考错误码表。 |
| 说明 | 下载指定消息中的附件(多媒体文件)。 注:App首先通过OnReceivedMessageEvent接口获得消息通知,然后再调用downloadMessageAttachment接口下载消息中的附件。 注:此接口为异步接口,可触发回调函数onDownloadMessageAttachmentProgressEvent和onDownloadMessageAttachmentEvent,分别用于获取下载进度和下载结果。 |
| 示例 |
char messageID[256] = { 0 };
char filePath[512] = { 0 };
CopyString(m_recGroupMsgID, messageID, 256);
CopyString(m_filePath, filePath, 512);
if(FreePPSDK::DownloadMessageAttachment(messageID, 0, filePath)!=0)
{
printf(“下载消息附件失败”);
}
|
响应消息下载结果
| 函数原型 | virtual void onDownloadMessageAttachmentEvent(char *messageID, int downloadResult) = 0; |
|---|---|
| 参数 | messageID:字符串,被下载的消息的唯一标识符。 downloadResult:整型,下载消息的结果。0=成功,其它值为下载失败的错误代码(参见附录2)。 |
| 返回值 | 无 |
| 说明 | APP通过此接口更新消息附件的下载状态。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此回调函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
voidFreePPSDKDelegate::onDownloadMessageAttachmentEvent(char *messageID, intdownloadResult)
{
CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
char msgID[256] = { 0 };
char groupMsgID[256];
CopyString(dlg->mmsTestDlg->m_sendMsgID, msgID, 256);
CopyString(dlg->mmsTestDlg->m_sendGroupMsgID, groupMsgID, 256);
if (strcmp(msgID, messageID) == 0) // 是否与当前发送的一对一消息匹配
{
//异步处理消息结果
}
elseif (strcmp(groupMsgID,messageID) == 0) // 是否与当前发送的群组消息匹配
{
//异步处理消息结果
}
}
|
响应消息附件的上传进度
| 函数原型 | virtual void onUploadMessageAttachmentProgressEvent(char *messageID,int uploadProgress) = 0; |
|---|---|
| 参数 | messageID:字符串,被上传消息的唯一标识符; uploadProgress:整型,上传文件进度的百分比。 |
| 返回值 | 无 |
| 说明 | APP可通过此回调函数更新文件上传的进度提示。 注:文件上传由sendMessage或sendGroupMessage接口发起。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此回调函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
voidFreePPSDKDelegate::onUploadMessageAttachmentProgressEvent(char *messageID, intuploadProgress)
{
//显示消息进度
}
|
响应消息附件下载进度
| 函数原型 | virtual void onDownloadMessageAttachmentProgressEvent(char* messageID, int downloadProgress) = 0; |
|---|---|
| 参数 | messageID:字符串,消息的唯一标识符; downloadProgress:整型,当前下载文件进度的百分比 |
| 返回值 | 无 |
| 说明 | APP可通过此回调函数更新文件下载的进度提示。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此回调函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
voidFreePPSDKDelegate::onDownloadloadMessageAttachmentProgressEvent(char *messageID, intdownloadProgress)
{
//CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
//char msgID[256];
//CopyString(dlg->mmsTestDlg->m_sendMsgID, msgID, 256);
//char msgGroupID[256];
//CopyString(dlg->mmsTestDlg->m_sendGroupMsgID, msgGroupID, 256);
//CString strUploadProgress = _T("");
//strUploadProgress.Format(_T("%d"), downloadProgress);
//strUploadProgress.Append(_T("%"));
//if (strcmp(msgID, messageID) == 0 || strcmp(msgGroupID, messageID) == 0)
//{
//显示消息进度
//}
}
|
群组管理
创建消息群组
| 函数原型 | int CreateGroupChat(char *groupName, char *memberArray,char *outGroupID); |
|---|---|
| 参数 | groupName:字符串,创建群组的主题。 memberArray:字符串,群组成员的通信号码列表。 outGroupID:输出参数,字符串,用于接收创建群组的信息。如果创建成功,则返回新建群组的唯一标识符。 |
| 返回值 | 整型,创建群组的结果。0=创建成功,其它值为错误代码。 |
| 说明 | 创建一个新的消息群组,并指定群组中的用户。 |
| 示例 |
if (m_groupName.GetLength() == 0 || m_memberArray.GetLength() == 0)
{
AfxMessageBox(_T("群组名为空或群组成员为空!"));
return;
}
char groupName[256] = { 0 };
char dstAccounts[1024] = { 0 };
// Unicode to Multibyte
CopyString(m_groupName, groupName, 256);
CopyString(m_memberArray, dstAccounts, 1024);
vector
|
邀请联系人加入消息群组
| 函数原型 | intJoinGroupChat(char *groupID, char *memberArray); |
|---|---|
| 参数 | groupID:字符串,创建群组时返回的群组标识符。 memberArray:JSON字符串,被邀请的群组成员的通信号码列表,例如: ["abner1","abner2","abner3","abner4"]。 |
| 返回值 | 整型,加入群组的结果。0=成功,其它参见附录2 |
| 说明 | 邀请用户加入指定的消息群组,被邀请的客户端会以即时消息的形式收到邀请通知。 |
| 示例 |
if (m_groupID.GetLength() == 0 || m_memberArray.GetLength() == 0)
{
AfxMessageBox(_T("群ID为空或邀请成员为空!"));
return;
}
char groupID[64] = { 0 };
char dstAccounts[1024] = { 0 };
CopyString(m_groupID, groupID, 64);
CopyString(m_memberArray, dstAccounts, 1024);
vector
|
退出消息群组
| 函数原型 | int LeaveGroupChat(char *groupID); |
|---|---|
| 参数 | groupID:字符串,群组的唯一标识符。 |
| 返回值 | 整型,离开群组的结果。0=成功,其它参见附录2 |
| 说明 | 退出指定的消息群组。 |
| 示例 |
if (m_groupID.GetLength() == 0)
{
AfxMessageBox(_T("群ID为空!"));
return;
}
char groupID[64] = { 0 };
CopyString(m_groupID, groupID, 64);
int Res = FreePPSDK::LeaveGroupChat(groupID);
if (Res != 0)
{
AfxMessageBox(_T("离开群组失败!"));
return;
}
else
{
AfxMessageBox(_T("离开群组成功!"));
}
|
获取指定群组信息
| 函数原型 | boolGetGroupChatInfo(char *groupID, GroupInfo* groupInfo); |
|---|---|
| 参数 | groupID:字符串,群组的唯一标识符。 groupInfo:群组对象( GroupInfo ),用于保存获取的群组信息。包含以下属性: groupID:字符串,群组唯一标识; ownerFreePPID:字符串,群创建者的通信号码; arrayMemberFreePPID:字符串数组,群成员的通信号码; createTime: 整型,创建群组的时间; groupName:字符串,群名称或主题; |
| 返回值 | 无 |
| 说明 | 获得指定群组的信息。 |
| 示例 |
if (m_groupID.GetLength() == 0)
{
AfxMessageBox(_T("群ID为空!"));
return;
}
GroupInfo* getGroupInfo = (GroupInfo*)malloc(sizeof(GroupInfo));
memset(getGroupInfo, 0, sizeof(GroupInfo));
int m_num = sizeof(GroupInfo);
char groupID[64] = { 0 };
CopyString(m_groupID, groupID, 64);
FreePPSDK::GetGroupChatInfo(groupID, getGroupInfo);
if (strlen(getGroupInfo->arrayMemberFreePPID) > 0)
{
CString messageString;
messageString.Format(_T("GetGroupInfo: ID = %s, Name = %s, Owner = %s,
Member = %s createTime = %d /n"), CStringW(getGroupInfo->groupID),CStringW(getGroupInfo->groupName),CStringW(getGroupInfo->ownerFreePPID),
CStringW(getGroupInfo->arrayMemberFreePPID), getGroupInfo->createTime);
m_mmsLogList.AddString(messageString);
}
|
获取当前登录用户的所有群组信息(该接口目前只在阿里云服务器上部署)
| 函数原型 | int GetGroupChatInfoList(char*groupsInfoBuf, int*groupsInfoBufLen); |
|---|---|
| 参数 | groupsInfoBuf:输出参数,JSON字符串,用于接收所有群组信息。例如: { "groups": [{"owner":"30902930", "mmsgroupid" : "30902930000004", "createtime" :"1435216718", "server" : "121.41.33.219", "groupname" :"GroupNameTest", "attendee" : ["30902930", "30904102", "30904646"]}, { "owner":"30902930", "mmsgroupid" : "30902930000002", "createtime" :"1435216717", "server" : "121.41.33.219", "groupname" : "GroupNameTest", "attendee" : ["30902930", "30904102", "30904646"] }, { "owner":"30902930", "mmsgroupid" : "30902930000003", "createtime" : "1435216717", "server" : "121.41.33.219", "groupname" : "GroupNameTest", "attendee" : ["30902930", "30904102", "30904646"] }]} groupsInfoBufLen:int型指针,传入接收BUF的长度。如果BUF长度不足以保存查询结果,返回保存结果所需的BUF长度。 |
| 返回值 | 整型,0=获取所有群组信息成功,-1=接收查询结果的BUF长度不够,其它值=错误代码。当返回-1时,groupsInfoBufLen返回接收结果所需的BUF长度。 |
| 说明 | 获得当前登录用户的所有群组信息。 注:若返回值为-1,表示用于接收结果的BUF长度不够,应用程序应该立即再调用一次,按照返回的长度信息,传入足够长度的BUF。 |
| 示例 |
char groupInfoList[2048] = { 0 };
int bufLen = sizeof(groupInfoList);
int res = FreePPSDK::GetGroupChatInfoList(groupInfoList, &bufLen);
if (-1 == res)
{
char* infoListBuf = (char*)malloc(bufLen);
memset(infoListBuf, 0, bufLen);
res = FreePPSDK::GetGroupChatInfoList(infoListBuf, &bufLen);
if (0 == res)
{
CString groupInfo = _T("");
wchar_t* wGroupInfoList = (wchar_t*)malloc(bufLen*sizeof(wchar_t));
wmemset(wGroupInfoList, 0, bufLen);
FreePPSDK::UTF8StringtoUnicodeCString(infoListBuf, wGroupInfoList, bufLen);
groupInfo = wGroupInfoList;
m_mmsLogList.AddString(groupInfo);
free(wGroupInfoList);
wGroupInfoList = NULL;
}
free(infoListBuf);
infoListBuf = NULL;
}
elseif (0 == res)
{
CString groupInfo = _T("");
wchar_t* wGroupInfoList = (wchar_t*)malloc(bufLen*sizeof(wchar_t));
FreePPSDK::UTF8StringtoUnicodeCString(groupInfoList, wGroupInfoList, bufLen);
groupInfo = wGroupInfoList;
m_mmsLogList.AddString(groupInfo);
}
|
辅助接口
UNICODE编码转UTF-8编码
| 函数原型 | int UnicodeCStringtoUTF8String(wchar_t*uniString,char*outUTF8String,int outStrBufLen); |
|---|---|
| 参数 | uniString:待转码的Unicode字符串。 outUTF8String:输出参数,接收转换后的UTF-8字符串的缓冲区。 outStrBufLen:接收UTF-8字符串的缓冲区长度。 |
| 返回值 | 整型,转码后UTF-8字符串的长度。 |
| 说明 | 将UNICODE编码字符串转换为UTF-8编码字符串。 |
| 示例 |
char memberArray[256] = { 0 };
int memberArrayLen = FreePPSDK::UnicodeCStringtoUTF8String(m_MemberArray.GetBuffer(0), memberArray, 256);// m_MemberArray为Unicode编码
|
UTF-8编码转UNICODE编码
| 函数原型 | int UTF8StringtoUnicodeCString(char*utf8String, wchar_t*outUniCString, int outStrBufLen); |
|---|---|
| 参数 | utf8String:待转码的UTF-8字符串。 outUniCString:输出参数,接收转码后的Unicode字符串的缓冲区。 outStrBufLen:接收Unicode字符串缓冲区长度。 |
| 返回值 | 整型,转码后UNICODE字符串长度。 |
| 说明 | 将UTF-8编码字符串转换为UNICODE编码字符串。。 |
| 示例 |
Message * messageOjbect = (Message *)msgObject;
wchar_t unicodeWchar[1024] = { 0 };
if (strlen(messageOjbect->textContent) > 0) //做UTF-8转UNICODE
{
int textLen = FreePPSDK::UTF8StringtoUnicodeCString(messageOjbect->textContent, unicodeWchar, 1024);
}
|
通话功能接口
通话功能接口的函数原型声明参见“FreePPSDKStream_C.h”文件,主要提供一对一语音或视频通话、语音会议、视频会议和媒体I/O设备(麦克风、扬声器和摄像头)控制等功能。
通话/会议控制
发起一对一的语音/视频通话呼叫
| 函数原型 | int MakeCall(const char *dstID, int media, char *outCallID); |
|---|---|
| 参数 | dstID:字符串,被叫用户的通信号码。 media:整型,通话的媒体类型。取值为 1=语音通话; 2=视频通话; outCallID:输出参数,字符串,通话的会话标识符(call-id)。 |
| 返回值 | 整型,0=呼叫成功,其它=错误代码,参见附录2。 |
| 说明 | 发起一对一的、免费的语音或视频通话。 注:此接口为异步接口,可触发回调函数onCallStateEvent。APP可根据此函数的返回值(call-id),在回调函数中匹配相应的通话状态通知。 注:如果是发起视频呼叫,APP需要先调用SetVideoDisplay杉树设置视频的远端和本地显示窗口。 |
| 示例 |
char callID[256] = {0};
switch (m_comboMediaType.GetCurSel())
{
case 0: // 语音呼叫
m_nCallMediaType = MEDIA_AUDIO_TYPE;
ret = FreePPSDK::MakeCall(dstFreePPIds.at(0).c_str(), m_nCallMediaType, callID);
break;
case 1: // 视频呼叫
m_nCallMediaType = MEDIA_VIDEO_TYPE; FreePPSDK::SetVideoDisplay(GetDlgItem(IDC_STATIC_REMOTE_VIDEO)->GetSafeHwnd(), GetDlgItem(IDC_STATIC_LOCAL_VIDEO)->GetSafeHwnd());
ret = FreePPSDK::MakeCall(dstFreePPIds.at(0).c_str(), m_nCallMediaType, callID);
break;
}
if(ret != 0)
{
AfxMessageBox(_T("呼叫失败"));
}
|
发起节费电话呼叫
| 函数原型 | int MakeOutboundCall(const char *phone, const char *via, char *outCallID); |
|---|---|
| 参数 | phone:字符串,被叫电话号码。 via:字符串,Outbound路由码。 outCallID:输出参数,字符串,通话的会话标识符(call-id)。 |
| 返回值 | 整型, 0=呼叫成功,其它=参见附录2. |
| 说明 | 发起一对一的、节费的outbound语音通话呼叫。 注:此接口为异步接口,可触发回调函数onCallStateEvent。APP可根据此函数的返回值(call-id),在回调函数中匹配相应的通话状态通知。 注:节费电话的收费标准,由Outbound Call的PSTN服务供应商提供,并可通过路由码区分不同的提供商。 |
| 示例 |
m_nCallMediaType = MEDIA_AUDIO_TYPE;
char dstOutbound[256] = {0};
char via[256] = {0};
UpdateData(true);
CopyString(m_szCallee, dstOutbound, 256);
CopyString(m_szRSHost2, via, 256);
ret = FreePPSDK::MakeOutboundCall(dstOutbound, via, callID);
if(ret < 0)
{
AfxMessageBox(_T("呼叫失败"));
}
|
结束通话
| 函数原型 | int HangupCall (char *callID); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符,一般由makeCall、makeOutboundCall、JoinConference或onReceiveCallEvent函数返回。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 结束一个通话(包括一对一或会议通话)或拒绝呼叫请求。 一对一通话:结束指定的一对一通话(主叫和被叫均可调用此函数)。此接口为异步接口,可触发回调函数onCallStateEvent。APP可根据此函数的返回值(call-id),在回调函数中匹配相应的通话状态通知。 对于客户端混音的会议通话:如果主持人调用此接口,且输入参数是会议标识符,则返回失败(主持人需调用HangupConference结束会议);如果与会者调用此接口,则挂断与主持人的通话,并触发回调函数onConferenceStateEvent。 对于服务器混音的会议通话:主持人和与会者均可调用此接口,结束自己的会议通话,并触发回调函数onConferenceStateEvent。 |
| 示例 |
if (m_szCallID.GetLength() != 0)
{
char callID[256]={0};
CopyString(m_szCallID, callID, 256);
ret = FreePPSDK::HangupCall(callID);
if (ret != 0)
{
AfxMessageBox(_T("挂断电话失败!!!"));
return;
}
}
|
接听通话请求
| 函数原型 | int AnswerCall (char *callID); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符或者会议室标识符,一般由onReceiveCallEvent回调函数返回。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 被叫用户接听指定的来电请求。 注:在呼叫建立时,被叫用户会收到onReceiveCallEvent通知,且APP可从通知中获得来电请求的callID。此callID即可以是一对一通话标识符,也可以是会议的会话标识符。如果用户接受来电请求,则APP需要调用此函数接听来电;如果用户拒绝来电请求,则APP需调用hangupCall函数拒绝接听。 接听电话后,APP将收到回调函数onCallStateEvent或onConferenceStateEvent。APP可根据通话标识符,在回调函数中匹配相应的此通话的状态通知。 |
| 示例 |
int ret = -1;
FreePPSDK::SetVideoDisplay(GetDlgItem(IDC_STATIC_REMOTE_VIDEO)->GetSafeHwnd(), GetDlgItem(IDC_STATIC_LOCAL_VIDEO)->GetSafeHwnd());
// 判断是否为一对一通话的标识符
if (m_szCallID.GetLength() != 0)
{
char callID[256];
CopyString(m_szCallID, callID, 256);
ret = FreePPSDK::AnswerCall(callID);
}
// 判断是否为会议通话的标识符
else if (m_szConfID.GetLength() != 0)
{
char confID[256];
CopyString(m_szConfID, confID, 256);
ret = FreePPSDK::AnswerCall(confID);
}
if (ret < 0)
{
AfxMessageBox(_T("接听失败"));
return;
}
|
通话保持或恢复
| 函数原型 | int HoldCall (char *callID,int hold); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符。 hold:整型,保持(1)或恢复(0)通话。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 保持或恢复指定的通话。 注:执行此操作后,APP将收到回调函数onCallStateEvent,并从通知中得到已进入保持或恢复状态。APP可根据通话标识符,在回调函数中匹配相应的此通话的状态通知。 |
| 示例 |
//hold按钮操作
int ret = -1;
if (m_szCallID.GetLength() != 0)
{
char callID[256] = {0};
CopyString(m_szCallID, callID, 256);
m_bHold = !m_bHold;
ret = FreePPSDK::HoldCall(callID, m_bHold);
if (ret == 0)
GetDlgItem(IDC_BUTTON_HOLD)->SetWindowText(m_bHold ? _T("Resume") : _T("Hold"));
}
//onCallStateEvent()中实现
caseCALL_STATE_ANSWER:
...
dlg->GetDlgItem(IDC_BUTTON_HOLD)->EnableWindow(true);
dlg->m_bHold = false;
break;
caseCALL_STATE_HOLD:
dlg->m_bHold = true;
break;
|
通话静音或取消静音
| 函数原型 | int MuteCall (char *callID,int mute); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符或者会议室标识符 mute:整型,麦克风静音(1)或取消静音(0)。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 麦克风(或会议室主持人)静音或取消静音。 注:目前只实现一对一通话的静音功能。 |
| 示例 |
int ret = -1;
staticint bMute = 1;
if (m_szCallID.GetLength() != 0)
{
char callID[256];
CopyString(m_szCallID, callID, 256);
bMute = !bMute;
ret = FreePPSDK::MuteCall(callID, bMute);
if (ret != 0)
{
AfxMessageBox(_T("静音失败"));
return;
}
GetDlgItem(IDC_BUTTON_MUTE)->SetWindowText(bMute ? _T("Unmute") : _T("Mute"));
}
|
发起通话录音
| 函数原型 | int StartMediaRecord (char *callID,const char* Utf8FilePath, int media, int format=0, int intervalSec=0); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符或者会议室标识符 Utf8FilePath:字符串,录音文件路径; meida:媒体类型,=1,audio;=2 video(暂不支持); format:整型,文件格式类型,0:mp3(默认),1:avi(暂不支持); intervalSec:整型,自动分段时间间隔,以秒为单位;默认为0,不分段。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 开始通话录音。 注:目前只实现一对一通话的录音功能。 |
| 示例 |
无
|
停止通话录音
| 函数原型 | int StopMediaRecord (char *callID); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符或者会议室标识符 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 停止通话录音。通过onRecordCallEvent()上报停止状态给app 注:目前只实现一对一通话的录音功能。 |
| 示例 |
无
|
发送DTMF拨号音
| 函数原型 | int SendDTMF (char *callID,char *digit, int time, int mode); |
|---|---|
| 参数 | callID:字符串,通话的会话标识符。 digit:字符串,所要发送的二次拨号数字。 time:整形,发送多个按键数字时的时间间隔,单位:ms(注:若只发送一个数字,则此参数可为0)。 mode:整形,DTMF信号传输模式。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 发送DTMF拨号音,完成二次拨号。 |
| 示例 |
|
发起语音或视频会议
| 函数原型 | int JoinConference(const char *dstFreePPIDs, int media, const char *serverConferenceID,const char *dstPhones, char *via, char *outConferenceID); |
|---|---|
| 参数 | dstFreePPIDs:JSON字符串,与会者的通信号码,可以邀请多个与会者。 media:整型,会议的媒体类型。3=语音会议,4=视频会议 serverConferenceID:字符串,会议室的通信号码。如果会议室号码为用户本身的通信号码,则采用客户端混音方式;否则采用服务器混音方式。 dstPhones:JSON字符串,与会者的电话号码。 via:字符串,Outbound路由码。 outConferenceID:输出参数,字符串,会议的会话标识符(conference-id)。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 创建一个语音/视频会议。 注:此接口为异步接口,可触发回调函数onConferenceStateEvent,并从通知中得到自己是否已进入会议室。APP可根据此函数的返回值(conference-id),在回调函数中匹配相应的会议状态通知。 注:只有当通话类型是语音会议(=3)或者视频会议(=4)时,serverConferenceID参数才有效。 注:对于采用服务器混音的会议,APP需预先申请会议室号码。此外,针对同一个会议室,此函数可以被多次调用,以邀请不同的与会者加入同一个会议。 |
| 示例 |
char dstAccounts[256]; //被邀请者的appCount
char svrConfID[256] = {0}; //会议室号码
int ret = -1;
//保存被叫的freeppID到dstFreePPs
CopyString(m_szCallee, dstAccounts, 256);// szCallee格式:123,456,3000
//保存会议室号码
CopyString(m_szSvrConfID, svrConfID, 256);
char confID[256];
vector
|
结束或退出会议
| 函数原型 | int HangupConference(char *conferenceID); |
|---|---|
| 参数 | conferenceID:字符串,会议的标识符,一般由JoinConference或onReceiveCallEvent函数返回。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | APP可通过此接口结束指定的会议,并挂断会议中的所有与会者。 注:执行此操作后,APP将收到回调函数onConferenceStateEvent通知,并从通知中得到会议的状态。APP可根据会议标识符,在回调函数中匹配相应的此通话的状态通知;当客户端混音时,主持人调用该接口可以挂断所有与会者,与会者调用该接口只能挂断自己的会话;当服务器混音时,所有人都能调用该接口挂断整个会议室。 |
| 示例 |
// m_szConfID :会话标识符
if (m_szConfID.GetLength() != 0)
{
if (m_szConfID.Compare(m_szSvrConfID) == 0 ||
m_szConfID.Compare(m_strHostFreePPID) == 0)
{
char confID[256];
CopyString(m_szConfID, confID, 256);
if(FreePPSDK::HangupConference(confID)==0)
{
m_szConfID = _T(""); // 结束会议成功,清除会议记录
}
}
}
|
刷新与会者列表
| 函数原型 | int ListConference(char *conferenceID); |
|---|---|
| 参数 | conferenceID:字符串,会议的会话标识符,一般由JoinConference函数或onReceiveCallEvent回调函数返回。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | APP通过此接口可获取会议中的与会者的状态。 注:执行此操作后,APP将收到回调函数onConferenceStateEvent通知,并从通知中得到当前的与会者状态。APP可根据会议标识符,在回调函数中匹配相应的此会议的状态通知。 |
| 示例 |
// m_szConfID :会话标识符
if (m_szConfID.GetLength() != 0)
{
char confID[256];
CopyString(m_szConfID, confID, 256);
FreePPSDK::ListConference (confID);
}
|
会议控制
| 函数原型 | int CtrlConference(char * conferenceID, int action, char *FreePPID); |
|---|---|
| 参数 | conferenceID:字符串,会议的会话标识符。一般由JoinConference函数或onReceiveCallEvent回调函数返回。 action:整型,要执行的控制动作。 0=踢出; 1=静音; 2=取消静音。 FreePPID:字符串,所控制的与会者的通信号码。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | APP可通过此接口对会议的与会者执行指定的会议控制动作。 目前只实现了踢人功能 注:此接口为异步接口,将触发回调函数onConferenceStateEvent。 APP可根据会议标识符,在回调函数中匹配相应的此通话的状态通知。 |
| 示例 |
// m_szConfID :会话标识符
// m_szConfCtrlFreeppID:将要被控制与会者的app账号
char confID[256];
char ctrlFreePPID[256];
CopyString(m_szConfID, confID, 256);
CopyString(m_szConfCtrlFreeppID,ctrlFreePPID,256);
vector
|
选择视频会议画面
| 函数原型 | int SubConferenceVideo(char* pubID); |
|---|---|
| 参数 | pubID:字符串,所要观看的与会者的通信号码。当pubID为NULL时,表示取消订阅,即不显示任何与会者的视频画面。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | APP可通过此接口,为视频会议中的参与者(包括主持人和与会者)选择所观看的视频画面。 注:SDK采用出版/订阅模型实现视频画面选择,每个与会者可以订阅自己想观看的视频画面。 |
| 示例 |
// m_szConfCtrlFreeppID:将要被控制与会者的APP账号
char ctrlFreePPID[1024];
CopyString(m_szConfCtrlFreeppID, ctrlFreePPID, 256);
vector
|
状态通知和查询
响应来电通知请求
| 函数原型 | Virtual void onReceiveCallEvent(char *callId, char *callerId, char *callerName, int media, int callType) = 0; |
|---|---|
| 参数 | callId:字符串,通话的会话或者会议室标识符。 callerId:字符串,主叫用户的通信号码。 callerName:字符串,主叫用户的昵称或电话号码。 media:整型,通话请求的媒体类型,取值为1=语音通话;2=视频通话;3=语音会议通话;4=视频会议通话。 callType:整型,来电通知的类型,取值为1=新来电,2=未接来电。 |
| 返回值 | 无 |
| 说明 | APP通过此接口接收其它用户的来电请求。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
//接口实现示例代码
void FreePPSDKDelegate::onReceiveCallEvent(char *callId, char *callerId, char *callerName, int media, int callType)
{
CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
CString callID(callId);
dlg->GetDlgItem(IDC_STATIC_PEER)->SetWindowText(callID);
//记录来电类型
dlg->m_nCallMediaType = media;
//根据来电媒体类型做界面处理并记录标识符
switch (dlg->m_nCallMediaType)
{
// 语音或视频会议
caseMEDIA_AUDIO_CONFERENCE_TYPE:
caseMEDIA_VIDEO_CONFERENCE_TYPE:
dlg->GetDlgItem(IDC_BUTTON_SUB_VIDEO)->EnableWindow(true);
dlg->GetDlgItem(IDC_BUTTON_KICK_ONE)->EnableWindow(true);
dlg->m_szConfID = callID;
dlg->m_szSvrConfID = callID;
break;
// 一对一语音或视频通信
caseMEDIA_AUDIO_TYPE:
caseMEDIA_VIDEO_TYPE:
dlg->m_szCallID = callID;
dlg->m_szSvrConfID = callID;
break;
default:
break;
}
//根据来电会话类型做界面处理
switch (callType)
{
caseRECEIVE_CALL_TYPE_INCOMING:// 来电通知
{
dlg->GetDlgItem(IDC_STATIC_INCOMING)->SetWindowText(_T("Calling You..."));
dlg->GetDlgItem(IDC_BUTTON_ANSWER)->EnableWindow(true);
dlg->GetDlgItem(IDC_BUTTON_REJECT)->EnableWindow(true);
}
break;
caseRECEIVE_CALL_TYPE_MISSED_CALL:// 未接电话通知
{
dlg->GetDlgItem(IDC_STATIC_INCOMING)->SetWindowText(_T("Missed Call You"));
dlg->GetDlgItem(IDC_BUTTON_ANSWER)->EnableWindow(false);
dlg->GetDlgItem(IDC_BUTTON_REJECT)->EnableWindow(false);
}
break;
default:
break;
}
char log[256] = {0};
sprintf(log,"onReceiveCallEvent:callID=%s,callerID=%s,callerName=%s,meida=%d,callType=%d\n", callId, callerId, callerName, media, callType);
dlg->PostMessage(WM_EVENT_LOG, NULL, (LPARAM)AllocStringBuffer(log));
|
响应通话状态改变通知
| 函数原型 | virtual void onCallStateEvent(char*callId,intstate,intreason) = 0; |
|---|---|
| 参数 | callId:字符串,一对一通话的会话标识符。 state:整型,当前的通话状态,取值为 0 – IDLE(待机); 1 – INITIATE(正在发起呼叫); 2 – ANSWER(已接听); 3 – HOLD(保持中); 4 – HANGUP(已挂断)。 有关通话状态的说明可参考3.2.2节。 reason:整型。当state为HANGUP时标识结束通话的原因,包括:被叫不在线、没有可用的网络连接、被叫忙等,参考附录4;当state为ANSWER时表示进入通话的途径,包括:0 - 接听电话;1 - 恢复通话。 |
| 返回值 | 无 |
| 说明 | APP通过此接口获知通话的状态发生改变的通知。在不同的通话状态下,APP应显示不同提示,例如:1) IDLE-无;2) NITIATE-正在呼叫中(主叫)或通话建立中(被叫);3) ANSWER-通话中;4) HOLD-通话保持中;5) HANGUP-通话结束。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
//接口实现示例代码
CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
char callID[256] = {0};
CString szHistory;
CopyString(dlg->m_szCallID, callID, 256);
if (strcmp(callID, callId) == 0)
{
switch (state)
{
caseCALL_STATE_IDLE:
szHistory.Format(_T("空闲:")); dlg->GetDlgItem(IDC_STATIC_OUTGOING)->SetWindowText(szHistory);
break;
caseCALL_STATE_INITIATE: // 正在发起呼叫
if (dlg->m_isOutGoingCall)
{
szHistory.Format(_T("呼出电话:"));
dlg->GetDlgItem(IDC_STATIC_OUTGOING)->SetWindowText(szHistory);
}
Else
{
szHistory.Format(_T("呼入电话:"));
dlg->GetDlgItem(IDC_STATIC_INCOMING)->SetWindowText(szHistory);
}
dlg->GetDlgItem(IDC_BUTTON_HANGUP)->EnableWindow(true);
break;
caseCALL_STATE_ANSWER:
szHistory.Format(_T("正在通话:"));
dlg->GetDlgItem(IDC_STATIC_OUTGOING)->SetWindowText(szHistory);
dlg->GetDlgItem(IDC_BUTTON_DIAL)->EnableWindow(false);
dlg->GetDlgItem(IDC_BUTTON_HANGUP)->EnableWindow(true);
dlg->GetDlgItem(IDC_BUTTON_ANSWER)->EnableWindow(false);
break;
caseCALL_STATE_HOLD:
szHistory.Format(_T("通话保持中"));
break;
caseCALL_STATE_HANGUP: // 结束通话时,恢复待机画面
dlg->GetDlgItem(IDC_BUTTON_DIAL)->EnableWindow(true);
dlg->GetDlgItem(IDC_BUTTON_HANGUP)->EnableWindow(false);
dlg->GetDlgItem(IDC_BUTTON_ANSWER)->EnableWindow(false);
dlg->GetDlgItem(IDC_BUTTON_REJECT)->EnableWindow(false);
dlg->GetDlgItem(IDC_STATIC_INCOMING)->SetWindowText(_T(""));
dlg->GetDlgItem(IDC_BUTTON_REJECT)->SetWindowText(_T("Reject"));
dlg->m_szCallID = _T("");
dlg->GetDlgItem(IDC_BUTTON_HOLD)->EnableWindow(false);
dlg->GetDlgItem(IDC_BUTTON_HOLD)->SetWindowText(_T("Hold"));
dlg->GetDlgItem(IDC_BUTTON_MUTE)->EnableWindow(false);
dlg->GetDlgItem(IDC_BUTTON_MUTE)->SetWindowText(_T("Mute"));
szHistory = _T("");
dlg->GetDlgItem(IDC_STATIC_OUTGOING)->SetWindowText(szHistory);
break;
default:
break;
}
char log[256] = {0};
sprintf(log, "onCallStateEvent:callID=%s,state=%d,reason=%d\n", callId, state,reason);
dlg->PostMessage(WM_EVENT_LOG, NULL, (LPARAM)AllocStringBuffer(log));
|
响应会议中与会者状态改变通知
| 函数原型 | virtual voidonConferenceStateEvent(char *conferenceId, char *callId, char *callerId, int state, int reason) = 0; |
|---|---|
| 参数 | conferenceId:字符串,会议的会话标识符,一般由JoinConference函数或onReceiveCallEvent回调函数返回(必须不为空)。 callId:字符串,与会者的通话标识符(可以为NULL)。 calleeId:字符串,与会者的通信号码。 state:整型,与会者当前的通话状态,取值为 1 – INITIATE(正在邀请); 2 – ANSWER(已进入); 3 – HANGUP(已离开)。 reason:整型。当state为HANGUP时,标识结束通话的原因,包括:被叫不在线、没有可用的网络连接、被叫忙等,参见附录4 - _call_hangup_reason;当state为ANSWER时表示进入通话的途径,包括:0 - 接听电话;1 - 恢复通话,参见附录4 - _call_answer_reason。 |
| 返回值 | 无 |
| 说明 | APP通过此接口可获得会议中某个与会者的状态发生改变的通知。在不同的通话状态下,APP应显示不同的与会者状态提示:1) INITIATE-正在呼叫中(主叫)或通话建立中(被叫);2) ANSWER-进入会议;3) HANGUP-离开会议。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
//接口实现示例代码
virtual void FreePPSDKDelegate::onConferenceStateEvent(char *conferenceId, char *callId, char *callerId, int state, int reason)
{
if (conferenceId == NULL || callerId == NULL ||strlen(conferenceId) == 0 || strlen(callerId) == 0)
{
return; // 参数错误
}
string strConventionerState;
CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
CString callerID(callerId);
switch (state)
{
caseCONFERENCE_STATE_INITIATE: // 正在邀请
strConventionerState = "1- INITIATE";
break;
caseCONFERENCE_STATE_ANSWER:
strConventionerState = "2-ANSWER"; // 已进入
break;
caseCONFERENCE_STATE_HANGUP: // 已离开
strConventionerState = "3-LEAVE";
break;
default:
break;
}
char log[512] = {0};
sprintf(log, "onConferenceStateEvent:freeppid=%s,state=%s,reason=%d\n", callerId,strConventionerState.c_str(),reason);
dlg->PostMessage(WM_EVENT_LOG, NULL, (LPARAM)AllocStringBuffer(log));
|
响应视频通信状态改变通知
| 函数原型 | virtual void onRemoteVideoStateEvent(char *callId,int state) = 0; |
|---|---|
| 参数 | callId:字符串,通话或会议的会话标识符。 state:整型,当前的通话的远端视频状态,取值为0=停止;1=开启。 |
| 返回值 | 无 |
| 说明 | APP通过此接口可获得视频通话中远端用户的视频发送状态的改变通知。在不同的视频状态下,APP可显示不同的界面。START:开启远端视频发送;STOP:停止远端视频发送。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
//接口实现示例代码
virtual voidonRemoteVideoStateEvent(char *callId,intstate)
{
CWinPhoneDlg *dlg = (CWinPhoneDlg *)theApp.m_pMainWnd;
char callID[256] = {0};
string szState;
CopyString(dlg->m_szCallID, callID, 256);
if (strcmp(callID, callId) == 0)
{
switch (state)
{
caseREMOTE_VIDEO_START: // 正在发送视频
szState = "0- START";
break;
caseREMOTE_VIDEO_STOP: // 停止发送视频
szState = "1- STOP";
break;
default:
break;
}
}
char log[512] = {0};
sprintf(log, "onRemoteVideoStateEvent:callid=%s,state=%s\n", callId, szState.c_str());
dlg->PostMessage(WM_EVENT_LOG, NULL, (LPARAM)AllocStringBuffer(log));
}
|
响应通话录音状态改变通知
| 函数原型 | virtual void onRecordStateEvent(char *filepath,int state) = 0; |
|---|---|
| 参数 | filepath:字符串,通话录音保存的文件名及路径。 state:整型,当前的通话录音状态,取值为1=开启;2=停止;3=转换成mp3完成。 |
| 返回值 | 无 |
| 说明 | APP通过此接口可获得录音状态的改变通知。在不同的状态下,APP可显示不同的状态通知。1:开启录音;2:停止录音3:转换mp3完成。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
无
|
查询通话的状态和信息
| 函数原型 | bool GetCallInfo(char *callID, FreePPCallInfo* callInfo); |
|---|---|
| 参数 | callId:字符串,通话的会话标识符。 callInfo:输出参数,FreePPCallInfo指针类型,通话状态信息 |
| 返回值 | 布尔类型, true=获取成功,false=失败,原因是callID不存在; |
| 说明 | 通过此接口,APP可获取指定通话的当前状态和详细信息,且将上述信息存放在FreePPCallInfo对象中返回。FreePPCallInfo对象包含如下属性: callId:字符串,通话或会议的会话标识符。 calleeId:字符串,对端用户的通信号码。 calleeName:字符串,对端用户的昵称或电话号码。 mediaType:整型,通话请求的媒体类型(语音、视频或会议)。 callState:整型,当前的通话状态,取值为:0 - IDLE;1 - INITIATE;2 - ANSWER;3 - HOLD;4 - HANGUP。 |
| 示例 |
无
|
获得当前正在进行的通话列表
| 函数原型 | void GetAllCallIDList(char *outCallIDList); |
|---|---|
| 参数 | outCallIDList:输出参数,JSON字符串,包含所有通话的会话标识符。APP获取JSON字符串后需要进行json解析。 |
| 返回值 | 无 |
| 说明 | 获取当前所有呼出和呼入通话的call-id字符串的列表。 注:APP可首先调用此函数获得call-id列表,然后再调用getCallInfo函数获得通话的状态和详细信息。 |
| 示例 |
无
|
媒体I/O管理
设置视频摄像头
| 函数原型 | int SetCamera (int device); |
|---|---|
| 参数 | device:整型,设备标识符。 注:-1为默认设备 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 设置当前视频通话所使用的摄像头。 |
| 示例 |
int ret = -1;
UpdateData(true);
ret = FreePPSDK::SetCamera(m_nCameraID);
if (ret !=0)
{
AfxMessageBox(_T("设置摄像头失败"));
return;
}
|
设置声音输出设备
| 函数原型 | int SetAudioOutput (int device); |
|---|---|
| 参数 | device:整型,扬声器设备标识符 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 设置声音输出设备 注:该功能未实现,采用默认设备输出。 |
| 示例 |
|
设置视频显示窗口
| 函数原型 | int SetVideoDisplay(void *displayRemote,void *displayPreview); |
|---|---|
| 参数 | displayRemote:指针类型,用于显示远端视频(对方的图像)的窗口对象。(注:对象类型需根据操作系统进行选择)。 displayPreview:指针类型,用于显示近端视频(自己的图像)的窗口对象(自己的图像)。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 设置视频通话中用于显示视频的窗口对象。 注:此接口需要在发起视频呼叫(MakeCall 或JoinConference)前或者收到视频来电请求接听后(AnswerCall之前)设置。 |
| 示例 |
int ret = -1;
ret=FreePPSDK::SetVideoDisplay(GetDlgItem(IDC_STATIC_REMOTE_VIDEO)->GetSafeHwnd(), GetDlgItem(IDC_STATIC_LOCAL_VIDEO)->GetSafeHwnd());
if(ret < 0)
{
AfxMessageBox(_T("设置视频显示窗口失败"));
}
|
开始视频发送
| 函数原型 | int StartVideoSend (); |
|---|---|
| 参数 | 无 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 手动开启本地视频的发送功能。 注:APP需通过SetParameter接口将"auto_send_video "参数设置为”0”时,此接口才有效。自动发送视频的模式包括: 0=手动,1=自动。SDK默认值为“1”,即视频通话接听后,自动发送本地视频。 |
| 示例 |
int ret = -1;
UpdateData(true);
ret = FreePPSDK::SetCamera(m_nCameraID);
if (ret < 0)
{
AfxMessageBox(_T("设置摄像头失败"));
return;
}
ret = FreePPSDK::StartVideoSend();
if (ret < 0)
{
AfxMessageBox(_T("开启视频发送失败"));
return;
}
|
停止视频发送
| 函数原型 | int StopVideoSend (); |
|---|---|
| 参数 | 无 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2. |
| 说明 | 停止本地视频发送。 |
| 示例 |
int ret = -1;
ret = FreePPSDK::StopVideoSend();
if (ret < 0)
{
AfxMessageBox(_T("停止视频发送失败"));
return;
}
|
设置通话请求的回铃音
| 函数原型 | int SetRingbackTone(char *ringbackFilePath); |
|---|---|
| 参数 | ringbackFilePath:字符串,App层Bundle或本地文件系统中回铃音文件的存储路径。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 设置电话呼叫的回铃音。格式为pcm 16K 注:该功能暂未实现,默认路径为数据库路径,文件名为ringbacktone.pcm。 |
| 示例 |
|
设置网络摄像头
| 函数原型 | int SetNetworkCamera(char *devURL, char* user, char* pass); |
|---|---|
| 参数 | devURL:字符串,网络摄像头的URL地址,即通过此URL地址SDK可以获得摄像头的有关服务信息,并自动连接摄像头的流媒体服务。 user:字符串(可选参数),访问网络摄像头的账号。 pass:字符串(可选参数),访问网络摄像头的密码。 resolution:整型,期望的视频分辨率。SDK将根据设备的实际能力,自动匹配与此参数最接近的视频分辨率。(参见附录4) quality:整型,期望的视频质量。SDK将根据设备的实际能力,自动匹配与此参数最接近的质量等级。(参见附录4) |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 设置SDK所使用的网络摄像头。一旦设置成功,则SDK将把网络摄像头的视频流作为本机采集的视频流发送给通话对端。 注:APP调用此函数时,SDK将自动连接指定的网络摄像头,以验证设备URL地址的有效性,但不会发送视频流。APP需通过调用StartVideoSend/StopVideoSend来控制视频流的发送。 |
| 示例 |
|
配置网络摄像头参数
| 函数原型 | int ConfigNetworkCamera(int width, int height, int framerate, int quality); |
|---|---|
| 参数 | width/height:整型,期望的视频分辨率(图像宽度和高度)。SDK将根据设备的实际能力,自动匹配与此参数最接近的视频分辨率。 framerate:整型,期望的视频帧速率。SDK将根据设备的实际能力,自动匹配与此参数最接近的视频帧速率。 quality:整型,期望的视频质量。取值范围为0-2,0为最低,2为最高。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=参见附录2。 |
| 说明 | 设置网络摄像头的工作参数。 注:若APP未设定网络摄像头的参数,则SDK默认按照352×288,25帧/s和中等质量水平工作。 |
| 示例 |
|
对讲功能接口
对讲功能接口的函数原型声明参见“FreePPSDKPTT_C.h”文件,主要提供进入或退出对讲频道、请求和释放发言权等控制功能。
频道/发言控制
进入语音对讲频道
| 函数原型 | int EnterPTTRoom(char * roomID) |
|---|---|
| 参数 | roomID: 语音对讲频道的通信号码。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=错误代码。 |
| 说明 | 进入预先分配的语音对讲频道,并自动处于收听语音状态。 注:此接口为异步接口,可触发回调函数onPTTStateEvent。APP可通过PTT状态通知得到是否已进入频道,以及对讲频道的当前状态。 注:语音对讲频道的通信号码需要预先申请。 |
| 示例 |
char dstAccounts[256] = { 0 };
int ret = -1;
// 转换字符编码格式
CopyString(m_szCallee, dstAccounts, 256); // dstAccount中为频道的通信号码
ret = FreePPSDK::EnterPTTRoom(dstAccounts);
If (! ret)
{
AfxMessageBox(_T("进入频道失败"));
}
|
退出语音对讲频道
| 函数原型 | int LeavePTTRoom(char * roomID) |
|---|---|
| 参数 | roomID: 语音对讲频道的通信号码。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=错误代码。 |
| 说明 | 退出一个已进入的语音对讲频道。 |
| 示例 |
char dstAccounts[256] = { 0 };
int ret = -1;
// 转换字符编码格式
CopyString(m_szCallee, dstAccounts, 256);
ret =FreePPSDK::LeavePTTRoom(dstAccounts);
|
请求发言
| 函数原型 | int PushTalk(char * roomID) |
|---|---|
| 参数 | roomID: 语音对讲频道的通信号码。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=错误代码。 |
| 说明 | 请求指定语音对讲频道的发言权,并等待发言。 注:此接口为异步接口,可触发回调函数onPTTStateEvent。APP可通过PTT状态通知得到是否已获得发言权。 |
| 示例 |
if (pMsg->message == WM_LBUTTONDOWN)
{
if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_Push)->m_hWnd)
FreePPSDK::PushTalk(dstAccounts);
}
else if (pMsg->message == WM_LBUTTONUP)
{
if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_Push)->m_hWnd)
FreePPSDK::ReleaseTalk(dstAccounts);
}
|
释放发言权
| 函数原型 | int ReleaseTalk(char * roomID) |
|---|---|
| 参数 | roomID: 语音对讲频道的FREEPP号码。 |
| 返回值 | 整型,操作是否成功。0=成功,其它=错误代码。 |
| 说明 | 释放指定频道的发言权,或取消发言请求 |
| 示例 |
参见PushTalk接口
|
频道状态通知
| 函数原型 | void onPTTStateEvent(char * roomID, int state, char * speaker, int position)=0; |
|---|---|
| 参数 | roomID: 语音对讲频道的通信号码。 state: 语音对讲频道的当前状态。取值如下: PTT_STATE_IDLE(当前频道空闲,没有发言者) PTT_STATE_GRANTED(本机用户获得发言权,并进入发言状态) PTT_STATE_RELEASED(本机用户释放发言权,并恢复收听状态) PTT_STATE_QUEUED (本机用户正在排队等待发言权) PTT_STATE_DENY(服务器拒绝本机用户的发言请求) PTT_STATE_TAKEN(频道已被占用,其它用户正在发言) PTT_STATE_ENTER(已进入语音对讲频道) Speaker:当state为PTT_STATE_TAKEN时,指当前发言者的通信号码。 Position: 当state为PTT_STATE_QUEUE时,指在本机用户前面排队的其它发言者的个数。 |
| 返回值 | 无 |
| 说明 | 通知APP语音对讲频道的当前状态( PTT状态机)及频道的使用情况。 注:此接口为回调函数接口,APP应在传递给SDK的FreePPSDKDelegate对象类中实现此函数。 注:APP不能在此回调接口中执行长时任务,以免阻塞SDK的回调任务。 |
| 示例 |
//接口实现示例代码
void FreePPSDKDelegate::onPTTStateEvent(char * roomID, int state, char * speaker, int position)
{
switch(state)
{
case PTT_STATE_IDLE:
break;
}
}
|
工作流程
启动流程
APP程序在启动时,应尽早完成SDK的初始化和AppKey认证工作。SDK运行时会产生用户数据库用于保存用户的相关信息,方便用户再次使用,在开始SDK初始化前需要设置数据库保存路径。启动流程如下图所示:
上图中,APP和SDK的具体交互流程如下:
- 1)调用SetParameter函数,设置用户数据库保存路径;
- 2)调用SetParameter函数,设置云端服务的入口地址;
- 3)调用Initialize函数,初始化SDK库,设置APP层的FreePPSDKDelegate代理对象;
- 4)调用BindAppAccount函数,验证客户端的合法性,绑定APP帐号并登录即时通信系统;
- 5)进入APP主界面。
一对一消息流程
上图中,APP和SDK的具体交互流程如下:
- 1)发送端调用QueryFreePPIDByAppAccount函数,根据用户的App账号获取目标用户的通信号码;
- 2)发送端调用SendMessage函数发送消息;
- 3)发送端通过onSendMessageEvent回调函数获得消息的发送结果;
- 4)如果是文件型消息,发送端可以通过onUploadMessageAttachmentProgressEvent回调函数获得文件的上传进度;
- 5)接收端通过onReceivedMessageEvent回调函数接收到消息通知;
- 6)如果是文件型消息,接收端调用DownloadMessageAttachment函数下载消息中的附件文件;
- 7)接收端通过onDownloadMessageAttachmentProgressEvent回调函数获得文件下载的进度;
- 8)接收端通过onDownloadMessageEvent回调函数得到下载消息文件的结果。
群组消息流程
上图中,APP和SDK的具体交互流程如下:
- 1)发送端调用CreateGroupChat函数创建群组时,或者通过onReceivedMessageEvent回调函数收到群组邀请时,获得群组ID;
- 2)发送端调用SendGroupMessage函数发送群组消息;
- 3)发送端通过onSendMessageEvent回调函数获得群组消息的发送状态;
- 4)如果是文件型消息,发送端可以通过onUploadMessageAttachmentProgressEvent回调函数获得文件的上传进度;
- 5)接收端通过onReceivedMessageEvent回调函数接收到消息通知;
- 6)如果是文件型消息,接收端调用DownloadMessageAttachment函数下载消息中的附件;
- 7)接收端通过onDownloadMessageAttachmentProgressEvent回调函数获得文件下载的进度,最后通过onDownloadMessageEvent回调函数得到下载消息文件的状态值。
基本通话流程
上图中,APP和SDK的具体交互流程如下:
- 1)主叫端调用MakeCall或MakeOutboundCall发起通话呼叫,并通过返回值获得通话的标识符(call-id);
- 2)主叫端通过onCallStateEvent:INITIATE状态通知,获得通话正在建立的状态;
- 3)被叫端通过onReceiveCallEvent回调函数,接收到来电通知,并获得通话的标识符(call-id);
- 4)被叫端调用AnswerCall接听来电;
- 5)被叫端通过onCallStateEvent回调函数,依次得到INITIATE和ANSWER状态;
- 6)主叫端通过onCallStateEvent:ANSWER状态通知,得知被叫端已接听电话,并进入通话状态;
- 7)无论主叫端或被叫端,均可调用HangupCall结束通话,并通过onCallStateEvent:HANGUP状态通知获知通话已结束。
拒接电话流程
上图中,APP和SDK的具体交互流程如下:
- 1)被叫端首先从onReceieveCallEvent回调函数中,获得通话的标识符(call-id);
- 2)被叫端拒接来电时,直接调用HangupCall函数;
- 3)主叫端和被叫端均通过onCallStateevent:HANGUP状态通知,获知通话已被拒接。
呼叫保留/恢复流程
上图中,APP和SDK的具体交互流程如下(以主叫端为例):
- 1)主叫端在通话接听后,调用HoldCall:1(参数为1)函数,进入呼叫保持状态。此时,SDK既不发送,也不接收语音;
- 2)主叫端和被叫端均通过onCallStateEvent:HOLD状态通知,获知指定的通话已经被保持。注:APP负责区分谁是保持动作的发起者;
- 3)主叫端调用HoldCall:0(参数为0)函数恢复通话。此时,SDK恢复语音和视频的发送及接收;
- 4)主叫端和被叫端均通过onCallStateEvent:ANSWER状态通知,获知指定的通话已经恢复。
基本会议流程
上图中,APP和SDK的具体交互流程如下:
- 1)主持人调用JoinConeference函数,向每个与会者发送会议邀请,如果是视频会议邀请,主持人默认先显示本地预览;
- 2)主持人通过onConferenceStateEvent:INITIATE状态通知,获得每个与会者的当前状态为正在邀请;
- 3)与会者通过onReceiveCallEvent回调函数,接收到主持人发送的会议邀请并提示用户;
- 4)用户接受邀请后,与会者调用AnswerCall函数接受会议邀请;
- 5)主持人通过onConferenceStateEvent回调函数,获知与会者进入会议室的状态;
- 6)与会者通过onConferenceStateEvent回调函数,分别获知自己的通话状态,以及所有与会者在会议室中的状态;
- 7)主持人或与会者调用HangupConference函数结束会议时,与会者通过onConferenceStateEvent回调函数,获知会议已结束;
- 8)与会者调用HangupCall挂断自己(客户端混音主持人调用HangupCall返回接口调用错误码:-53),所有与会者通过onConferenceStateEvent回调函数获知与会者离开会议室。
会议拒接流程
上图中,APP和SDK的具体交互流程如下:
- 1)主持人调用JoinConeference函数,向每个与会者发送会议邀请;
- 2)主持人通过onConferenceStateEvent:INITIATE状态通知,获得每个与会者的当前状态为正在邀请;
- 3)与会者通过onReceiveCallEvent回调函数,接收到主持人发送的会议邀请并提示用户;
- 4)用户拒接邀请后,与会者调用HangupCall函数拒接会议邀请;
- 5)主持人通过onConferenceStateEvent回调函数,获知与会者离开会议室的状态;
- 6)与会者通过onConferenceStateEvent回调函数,分别获知自己的通话状态,以及所有与会者在会议室中的状态。
会议控制流程
上图中,所有与会者都进入会议后,APP和SDK的具体交互流程如下:
- 1)与会者A调用CtrlConeference:B函数,踢出与会者B,并通过onConferenceStateEvent:HANGUP通知提示与会者B离开会议室;
- 2)与会者B及其他与会者通过onConferenceStateEvent: HANGUP状态通知,获知与会者B离开会议室的状态。
视频控制流程
上图为视频会议订阅流程,所有与会者都进入会议后,APP和SDK的具体交互流程如下:
- 1)在视频会议中,无论主持人或与会者,都可以通过调用SubConferenceVideo函数,选择所要观看的与会者视频画面。(注:默认情况下,客户端混音与会者端显示主持人视频,主持人不显示远端视频;服务器混音所有与会者只显示本地视频,不显示远端视频);
- 2)与会者可以互相订阅对方的视频;
- 3)取消视频订阅:当SubConferenceVideo:0时,取消视频订阅,远端视频无显示;
- 4)在视频通话中(包括一对一和会议),客户端可以调用StartVideoSend函数,允许发送本机视频;客户端可以调用StopVideoSend函数,停止发送本机视频。
语音对讲流程
上图中,APP和SDK的具体交互流程如下:
- 1)发言者和收听者首先调用EnterPTTRoom函数,进入语音对讲频道;
- 2)发言者和收听者可通过onPTTStateEvent:ENTER状态通知,获知自己和其它参与者进入语音对讲频道的状态;
- 3)发言者调用PushTalk函数,向对讲频道请求发言权;
- 4)发言者通过onPTTStateEvent:GRANTED状态通知,获知已获得发言权,然后开始发言;
- 5)收听者通过onPTTStateEvent:TAKEN状态通知,获知对讲频道已被占用,并开始收听发言;
- 6)发言者调用ReleaseTalk函数,释放发言权;
- 7)发言者通过onPTTStateEvent:RELEASED状态通知,获知发言权已被释放,并重新进入收听状态;
- 8)收听者通过onPTTStateEvent:IDLE状态通知,获知对讲频道进入空闲状态;
- 9)发言者和收听者可调用LeavePTTRoom函数,退出语音对讲频道。
开发环境配置
4.5.1 Windows
Visual Studio 2013或以上版本。